package com.txc.common.utils.jwt;

import com.txc.common.global.exception.CustomException;
import com.txc.common.global.result.ResultCode;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;


import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;

/**
 * @ClassName: JwtTokenUtil
 * @Author: TXC
 * @Date: 2023-07-30 16:36
 **/
public class JwtTokenUtil {
    /**
     * JWT创建token
     *
     * @param secretKey jwt密钥
     * @param claims    设置的信息
     * @param expire    过期时间
     * @return token
     */
    public static String createToken(String secretKey, Map<String, Object> claims, long expire) {
        // 生成JWT的时间
        long expMillis = System.currentTimeMillis() + expire;
        Date exp = new Date(expMillis);
        //生成 HMAC 密钥，根据提供的字节数组长度选择适当的 HMAC 算法，并返回相应的 SecretKey 对象。
        SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
        // 设置jwt的body
        JwtBuilder builder = Jwts.builder()
                // 设置签名使用的签名算法和签名使用的秘钥
                .signWith(key)
                // 如果有私有声明，一定要先设置这个自己创建的私有的声明，这个是给builder的claim赋值，一旦写在标准的声明赋值之后，就是覆盖了那些标准的声明的
                .claims(claims)
                // 设置过期时间
                .expiration(exp);
        return builder.compact();
    }


    /**
     * 解析token
     *
     * @param token     token
     * @param secretKey jwt密钥
     * @return Jws<Claims>
     */
    public static Claims parserToken(String token, String secretKey) {
        //生成 HMAC 密钥，根据提供的字节数组长度选择适当的 HMAC 算法，并返回相应的 SecretKey 对象。
        SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));

        // 得到DefaultJwtParser
        JwtParser jwtParser = Jwts.parser()
                // 设置签名的秘钥
                .verifyWith(key)
                .build();
        try {
            Jws<Claims> jws = jwtParser.parseSignedClaims(token);
            return jws.getPayload();
        } catch (ExpiredJwtException exception) {
            throw new CustomException(ResultCode.USER_ACCOUNT_EXPIRED);
        }
    }
}
